//
//  Converter.swift
//  Algorithms
//
//  Created by Archer on 2018/8/4.
//  Copyright © 2018年 Archer. All rights reserved.
//

import Foundation

/// 默认容量
public let kVectorDefaultCapacity = 10
/// 默认装填因子(a.k.a resize factor)
public let kVectorDefaultLoadFactor = 0.25

/// 向量定义
public final class Vector<Element> {
    /// 位置定义
    public typealias Index = Int
    
    /// 规模
    var _size: Int
    /// 容量
    var _capacity: Int
    /// 底层存储区
    var _storage: UnsafeMutablePointer<Element>
    
    /// 构造一个容量为capacity的空向量
    public init(capacity: Int = kVectorDefaultCapacity) {
        _size = 0
        _capacity = capacity
        _storage = Allocator.allocate(_capacity, for: Element.self)
    }
    
    /// 通过另一个向量初始化
    public convenience init(_ other: Vector<Element>) {
        self.init(vector: other, startIndex: other.startIndex, endIndex: other.endIndex)
    }
    
    public convenience init(other vector: Vector<Element>, range: CountableRange<Index>) {
        self.init(vector: vector, startIndex: range.lowerBound, endIndex: range.upperBound)
    }
    
    public convenience init(other vector: Vector<Element>, range: CountableClosedRange<Index>) {
        self.init(vector: vector, startIndex: range.lowerBound, endIndex: range.upperBound.advanced(by: 1))
    }
    
    /// 通过另一个向量的指定区间初始化
    init(vector: Vector<Element>, startIndex: Index, endIndex: Index) {
        precondition(startIndex >= 0 && startIndex <= endIndex, "Index不能为负数且startIndex不能大于endIndex")
        precondition(endIndex <= vector.endIndex, "指定区间(\(startIndex)-\(endIndex))超过\(vector)的容量")
        _size = 0 // 规模清零
        _capacity = 2 * (endIndex - startIndex) // 预留空间
        _storage = Allocator.allocate(_capacity, for: Element.self) // 分配存储空间
        for i in startIndex..<endIndex { // 逐成员复制
            _storage[_size] = vector._storage[i]
            _size += 1
        }
    }
    
    /// include
    public var startIndex: Index { return 0 }
    /// not include
    public var endIndex: Index { return _size }
    public var isEmpty: Bool { return count == 0 }
    public var count: Int { return endIndex - startIndex }
    public var indices: CountableRange<Index> { return startIndex..<endIndex }
    
    public var first: Element? {
        get {
            if isEmpty { return nil }
            return _storage[0]
        }
    }
    
    public var last: Element? {
        get {
            if isEmpty { return nil }
            return _storage[_size - 1]
        }
    }
    
    public func forEach(_ body: (Element) throws -> Void) rethrows { for i in indices { try body(_storage[i]) } }
    
    deinit {
        _size = 0
        _capacity = 0
        _storage.deallocate()
        debugPrint(String(format: "\(self) = %p is deinitializing", UInt(bitPattern: ObjectIdentifier(self))))
    }
}

/// 克隆 FIXME: Element comfirms to Cloneable
extension Vector: Cloneable where Element: Cloneable {
    public func clone() -> Vector<Element> {
        let copy = Vector(capacity: _capacity)
        for i in indices { // 逐成员复制
            copy._storage[copy._size] = _storage[i].clone()
            copy._size += 1
        }
        return copy
    }
}

/// 数组字面量初始化
extension Vector: ExpressibleByArrayLiteral {
    public convenience init(arrayLiteral elements: Element...) {
        self.init(capacity: elements.count * 2)
        for i in elements.indices {
            _storage[_size] = elements[i]
            _size += 1
        }
    }
}

extension Vector: CustomStringConvertible {
    public var description: String {
        var s = "["
        for i in indices {
            s += "\(_storage[i])"
            if i != (_size - 1) {
                s += ", "
            }
        }
        return s + "]"
    }    
}
